package com.jdbc.jdbc;

import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JDBC-4
 * Description: JDBC实现CRUD
 *
 * TODO：
 *  1. 使用org.junit.Test测试
 *  2. 查询操作将结果集 ResultSet 保存到 List<Map>中
 *
 * JDBC步骤
 * 1. 注册驱动
 * 2. 获取连接
 * 3. 创建对象
 * 4. 执行SQL
 * 5. 结果解析
 * 6. 关闭资源
 */
public class JdbcPreparedStatementCrudPart {

    /**
     * 插入一条用户数据 (test,test,测试)
     */
    @Test
    public void testInsert() throws Exception{

        // 1. 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        // 2. 获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "root");

        // 3. 编写SQL语句，动态值用 ? 占位
        String sql = "insert into t_user(account,password,nickname) values (?,?,?);";

        // 4. 创建PrepareStatement
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        // 5. 占位符赋值，可以使用setString(1, "test"); setObjcet(2, "test");
        preparedStatement.setString(1, "test2");
        preparedStatement.setObject(2, "test");
        preparedStatement.setString(3, "测试");

        // 6. 发送SQL语句，DML类型使用executeUpdate()
        int rows = preparedStatement.executeUpdate();

        // 7. 输出结果
        if (rows > 0) {
            System.out.println("数据插入成功");
        } else {
            System.out.println("数据插入失败！");
        }
        System.out.println(rows);

        // 8. 关闭资源close
        preparedStatement.close();
        connection.close();
    }

    /**
     * 修改一条用户数据
     * 修改账号: test的用户,将nickname改为tomcat
     */
    @Test
    public void testUpdate() throws Exception{

        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "root");

        //编写SQL
        String sql = "update t_user set nickname = ? where id = ? ;";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //占位符赋值
        preparedStatement.setString(1, "tomcat");
        preparedStatement.setObject(2, 3);

        //发送SQL语句
        int rows = preparedStatement.executeUpdate();

        //输出结果
        if (rows > 0) {
            System.out.println("修改成功");
        } else {
            System.out.println("修改失败！");
        }

        //关闭资源close
        preparedStatement.close();
        connection.close();
    }

    /**
     * 删除一条用户数据
     * 账号id: test
     */
    @Test
    public void testDelete() throws Exception{

        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "root");

        //编写SQL
        String sql = "delete from t_user where id = ? ;";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //占位符赋值
        preparedStatement.setObject(1, 5);

        //发送SQL语句
        int rows = preparedStatement.executeUpdate();

        //输出结果
        if (rows > 0) {
            System.out.println("数据删除成功");
        } else {
            System.out.println("数据删除失败！");
        }

        //关闭资源close
        preparedStatement.close();
        connection.close();
    }

    /**
     * 查询全部数据，并将数据存到List<Map>中
     *
     * 步骤:
     *    1.创建一个List<Map>集合
     *    2.遍历结果集resultSet
     *    3.每行数据存储到一个map对象
     *    4.将对象存到List<Map>中
     *    5.最终返回
     *
     * TODO:
     *    1. 通过 ResultSetMetaData 获取列信息：字段名 getColumnLabel(int column)、字段个数 getColumnCount()
     *    2. map -> 对应一行数据
     *       map key -> 数据库列名或者别名
     *       map value -> 数据库列的值
     */
    @Test
    public void testQueryMap() throws Exception{

        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "root");

        //编写SQL
        String sql = "select id,account,password,nickname from t_user ;";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //占位符赋值 本次没有占位符,省略

        //发送查询语句，查询语句使用executeQuery()
        ResultSet resultSet = preparedStatement.executeQuery();

        //创建一个集合，使用Object
        List<Map> mapList = new ArrayList<>();

        // TODO：通过 ResultSetMetaData 获取列信息对象，可以获取字段名、字段个数
        ResultSetMetaData metaData = resultSet.getMetaData();

        // 获取字段个数
        int columnCount = metaData.getColumnCount();

        while (resultSet.next()) {
            Map map = new HashMap();

            // 不推荐，按列名手动保存
//            map.put("account", resultSet.getInt("account"));
//            map.put("password", resultSet.getInt("password"));
//            map.put("nickname", resultSet.getInt("nickname"));

            // 推荐自动化，注意数据库下标都从1开始
            for (int i = 1; i <= columnCount; i++) {
                // ResultSetMetaData通过下标获取字段名，TODO：getColumnLabel() 会获取别名，没有别名的是字段名,不要使用 getColumnName()
                String columnLabel = metaData.getColumnLabel(i);
                // resultSet通过下标获取字段值
                Object object = resultSet.getObject(i);
                map.put(columnLabel, object);
            }
            mapList.add(map);
        }

        System.out.println(mapList);

        //关闭资源close
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

}
